#ftplistparse

import locale
import re

re_ymd = [
	re.compile(r'(?P<ymd>^\d{1,4}.*?\d{1,2}.*?\d{1,2}.*?\s+)'),
	re.compile(r'(?P<mdt>^\d{1,2}.*?\d{1,2}.*?\s*\d{1,2}:\d{1,2}\s+)'),
	re.compile(r'(?P<smdt>^(?i)(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s*\d{1,2}\s*\d{1,2}:\d{1,2}\s+)'),
	re.compile(r'(?P<smdy>^(?i)(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\s*\d{1,2}\s*\d{1,4}\s+)'),
	]

def ftplistparse(lines, Unicode=False, callback=None):
	dirs = []
	files = []
	for line in lines:
		t = analyseline(line)
		if not t:
			continue
		dir, perm, size, filename = t
		if Unicode:
			filename = encodestring(filename)
		if filename in ('.', '..'):
			continue
		if dir:
			dirs.append((filename, '', perm, 0))
		else:
			if callback:
				if not callback(filename):
					files.append((filename, size, perm, 1))
			else:
				files.append((filename, size, perm, 1))

	dirs.sort()
	files.sort()

	return dirs, files

months = ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"]

def encodestring(s, encoding=None):
	if not encoding:
		encoding = locale.getdefaultlocale()[1]
	if encoding:
		s = unicode(s, encoding)
	return s

def getmonth(month):
	if len(month) == 3:
		month = month.lower()
		if month in months:
			 return months.index(month) + 1
	return -1

def analyseline(line):
	trydir = 0
	tryfile = 0
	if line and line[0] in ('c', 'd', 'l', 'p', 's', '-'):
		if line[0] == 'd':
			trydir = 1

		state = 1
		i = 0
		for j in range(0, len(line)):
			ch = line[j]
			if ch == ' ' and line[j + 1] != ' ':
				s = line[i:j].strip()
				if state == 1:		#get perm
					perm = s
					state = 2
				elif state == 2:	#skip nlink
					state = 3
					if (j - i == 6) and (line[i] == 'f'):
						state = 4
				elif state == 3:	#skip uid
					state = 4
				elif state == 4:	#skip gid
					state = 5
				elif state == 5:	#get size
					size = int(s)
					flag = False
					filename = ''
					text = line[j+1:].strip()
					for r in re_ymd:
						result = r.search(text)
						if result:
							flag = True
							filename = text[result.end():]
							break
					state = 6
				elif state == 6:
					continue

				i = j + 1
				while i < len(line) and line[i] == ' ':
					i = i + 1

		if state != 6:
			return False

		if line[0] == 'l':
			pos = filename.find('->')
			if pos > -1:
				filename = filename[:pos-1]

		return trydir, perm, size, filename

if __name__ == '__main__':
	lists = [
		'drwxr-xr-x   18 179      666          4096 Oct 10 15:38 Python-2.3.4',
		'-rw-r--r--    1 501      501       8502738 Oct 10 15:31 Python-2.3.4.tgz',
		'srwxrwxr-x    1 500      500             0 Sep 15 22:31 MQSeries.1147',
		"-rw-r--r--   1 root     other        531 Jan 29 03:26 README",
		"dr-xr-xr-x   2 root     other        512 Apr  8 1994  etc",
		"dr-xr-xr-x   2 root     other        512 Apr  8  1994 lib",
		"lrwxrwxrwx   1 root     other          7 Jan 25 00:17 bin -> usr/bin",
		"----------   1 owner    group         1803128 Jul 10 10:18 ls-lR.Z",
		"d---------   1 owner    group               0 May  9 19:45 Softlib",
		"-rwxrwxrwx   1 noone    nogroup      322 Aug 19  1996 message.ftp",
		]
	dirs, files = ftplistparse(lists)
	print 'dirs-------------------'
	for v in dirs:
		print v
	print 'files------------------'
	for v in files:
		print v